package App.Repository;

import App.Job.MyJob;
import App.Model.Account.CrmDataItem;
import App.Model.Account.CrmUser;
import App.Model.BaseEnum;
import App.Model.Friend.*;
import App.Model.Task.*;
import App.Service.TecentIMService;
import App.Utility.StringUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.hibernate.Transaction;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
//import sun.util.resources.cldr.rm.CalendarData_rm_CH;

import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Calendar;
import java.util.stream.Collectors;

/**
 * Created by xw on 2019/1/14.
 */
@Repository
public class FriendRepository extends BaseRepository {

    //新增
    @Transactional
    public int insertFriend(FriendSaveRequest _request, int userid) throws Exception {
        int _result = 0;
        int _finalResult = 0;
        try {
            List<CrmFriendPart> _friends = getMyfriends(userid);
            List<Integer> _ids = _request.getUserids();
            String _strSql = "insert into crm_my_contact (recid,myuserid,userid,reccreator)values(:recid,:myuserid,:userid,:reccreator);";
            for (Integer id : _ids) {
                //过滤重复的数据
                List<CrmFriendPart> _tmp = _friends.stream().filter(x -> x.getUserid() == id).collect(Collectors.toList());
                if (_tmp != null && _tmp.size() > 0) {
                    continue;
                }
                String _recid = UUID.randomUUID().toString();
                Map<String, Object> _params = new HashMap<>();
                _params.put("recid", _recid);
                _params.put("myuserid", userid);
                _params.put("userid", id);
                _params.put("reccreator", userid);
                _result = updateEntity(_strSql, _params);
                _finalResult += _result;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
        return _finalResult;
    }

    //删除
    @Transactional
    public int deleteFriend(FriendDeleteRequest _request, int userid) throws Exception {
        int _result = 0;
        int _finalResult = 0;
        try {
            List<String> _ids = _request.getRecids();
            String _strSql = "update crm_my_contact set recstatus=0 where recid=:recid";
            for (String id : _ids) {

                //get contact
                String _strGetSql = "select recid, myuserid,userid from crm_my_contact where recid=:recid ";
                Map<String, Object> _params = new HashMap<>();
                _params.put("recid", id);
                List<CrmContract> _contacts = getEntitys(_strGetSql, _params, CrmContract.class);

                if (_contacts != null && _contacts.size() > 0) {
                    int _friendid = _contacts.get(0).getUserid();
                    String _strGetFriendSql = "select recid, myuserid,userid from crm_my_contact where myuserid=:myuserid and userid=:userid ";
                    _params.clear();
                    _params.put("myuserid", _friendid);
                    _params.put("userid", userid);
                    List<CrmContract> _friends = getEntitys(_strGetFriendSql, _params, CrmContract.class);
                    if (_friends != null && _friends.size() > 0) {
                        for (CrmContract c : _friends) {
                            _params.clear();
                            _params.put("recid", c.getRecid());
                            updateEntity(_strSql, _params);
                        }
                    }
                }
                _params.clear();
                _params.put("recid", id);
                _result = updateEntity(_strSql, _params);
                _finalResult += _result;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
        return _finalResult;
    }

    //列表
    public List<FriendListResponse> getFriendList(FriendListRequest _request, int userid) {
        List<FriendListResponse> _friends = new ArrayList<>();
        try {
            String _searchKey = _request.getSearchkey();
            String _strSql = " select m.recid, u.id,u.realname,u.username,u.headimage,u.gender,u.title,u.company,u.address,u.signature " +
                    " from crm_my_contact m " +
                    " inner join crm_user u on m.userid=u.id " +
                    " where m.recstatus=1 " +
                    " and  m.myuserid=:myuserid  " +
                    " and ( u.realname like" + "'%" + _searchKey + "%' or u.username like" + "'%" + _searchKey + "%' ) ";

            String _orderby_sql = " order by m.createtime desc  ";
            _strSql += _orderby_sql;

            if(_request.getPageindex() > 0){
                int _pageindex = _request.getPageindex();
                int _pageSize = _request.getPagesize();
                int _offset = (_pageindex - 1) * _pageSize;
                _strSql += " limit " + _pageSize + " offset " + _offset;
            }
            Map<String, Object> _params = new HashMap<>();
            _params.put("myuserid", userid);
            List<CrmFriend> _tmpFriends = getEntitys(_strSql, _params, CrmFriend.class);
            _friends = toFriendListReponseBath(_tmpFriends);

        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
        return _friends;
    }

    public List<FriendListResponse> getFriendSearchList(FriendListRequest _request, int userid) {
        List<FriendListResponse> _friends = new ArrayList<>();
        try {
            String _searchKey = _request.getSearchkey();
            String _strSql = " select m.recid, u.id,u.realname,u.username,u.headimage,u.gender,u.title,u.company,u.address,u.signature " +
                    " from crm_my_contact m " +
                    " inner join crm_user u on m.userid=u.id " +
                    " where m.recstatus=1 " +
                    " and  m.myuserid=:myuserid  " +
                    " and ( u.realname like" + "'%" + _searchKey + "%' ) ";

            String _orderby_sql = " order by m.createtime desc  ";
            _strSql += _orderby_sql;

            if(_request.getPageindex() > 0){
                int _pageindex = _request.getPageindex();
                int _pageSize = _request.getPagesize();
                int _offset = (_pageindex - 1) * _pageSize;
                _strSql += " limit " + _pageSize + " offset " + _offset;
            }
            Map<String, Object> _params = new HashMap<>();
            _params.put("myuserid", userid);
            List<CrmFriend> _tmpFriends = getEntitys(_strSql, _params, CrmFriend.class);
            _friends = toFriendListReponseBath(_tmpFriends);

        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
        return _friends;
    }

    public List<FriendContactListResponse> getContactList(FriendListRequest _request, int userid) {
        List<FriendContactListResponse> _friends = new ArrayList<>();
        try {
            String _searchKey = _request.getSearchkey();


            String _strSql = " select id,username,headimage,realname,gender,title,company,address,signature  " +
                    " from crm_user " +
                    " where recstatus=1 and  id not in (select userid from crm_my_contact where recstatus=1 and  myuserid=:myuserid) " +
                    " and ( realname =" + "'" + _searchKey + "' or username =" + "'" + _searchKey + "') ";

            Map<String, Object> _params = new HashMap<>();
            _params.put("myuserid", userid);
            List<CrmUserPart> _tmpFriends = getEntitys(_strSql, _params, CrmUserPart.class);
            _friends = toContactListReponseBath(_tmpFriends);

        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
        return _friends;
    }

    //获取用户信息
    public FriendMeResponse getUserInfo(int userId) {
        FriendMeResponse _response = new FriendMeResponse();
        try {
            String _strSql = " select u.id,u.username,u.headimage,u.realname,u.gender,u.title,u.company,u.address,u.signature, " +
                    " u.resume,u.birthdate,u.experience,u.education,u.socialfun,u.reward, ua.expertiseids as expertiseids,languageids " +
                    " from crm_user u " +
                    " left join crm_user_auth ua on u.id = ua.userid " +
                    " where id=:id ";

            Map<String, Object> _params = new HashMap<>();
            _params.put("id", userId);
            List<CrmUserPart2> _meList = getEntitys(_strSql, _params, CrmUserPart2.class);
            if (_meList != null && _meList.size() > 0) {
                CrmUserPart2 _me = _meList.get(0);
                String expertiseids = _me.getExpertiseids();
                List<CrmUserExpertise> exs = new ArrayList<CrmUserExpertise>();

                if(expertiseids != null){
                    String[] expertiseidsArray = expertiseids.split(",");
                    if(expertiseidsArray != null){
                        for (String str : expertiseidsArray) {
                            int expertiseId = Integer.parseInt(str);
                            List<CrmUserExpertise> ex = getExpertises(userId, expertiseId);
                            if(ex != null){
                                exs.add(ex.get(0));
                            }
                        }
                    }
                }

                _response = toFriendMeResponse(_me);
                _response.setExpertise(exs);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
        return _response;
    }

    public FriendMeResponse getUserInfo(int userId, int myUserId) {
        FriendMeResponse _response = getUserInfo(userId);
        boolean isMyFriend = isMyFriend(userId, myUserId);
        _response.setIsmyfriend(isMyFriend);

        return _response;
    }

    public boolean isMyFriend(int userId, int myuserId){
       boolean isMyFriend = false;

        String _strSql = " select count(1) from crm_my_contact  where recstatus = 1 and userid=:userid and myuserid =:myuserid limit 1 ";
        Map<String, Object> _params = new HashMap<>();
        _params.put("userid", userId);
        _params.put("myuserid", myuserId);
        BigInteger _count = getEntitValue(_strSql, _params);
        if(_count != null && _count.intValue() > 0){
            isMyFriend = true;
        }

        return  isMyFriend;
    }

    public List<CrmUserExpertiseResponse> getExpertisesList(int userId){
        List<CrmUserExpertiseResponse> responses = new ArrayList<>();

        String _strSql = " select expertiseids from crm_user_auth  where recstatus = 1 and userid=:userid limit 1 ";
        Map<String, Object> _params = new HashMap<>();
        _params.put("userid", userId);
        String _expertiseids = getEntitValue(_strSql, _params);
        if(_expertiseids != null){
            String[] expertiseidsArray = _expertiseids.split(",");
            for(String str :expertiseidsArray){
                CrmUserExpertiseResponse res = new CrmUserExpertiseResponse();
                int expertiseId = Integer.parseInt(str);
                List<CrmUserExpertise> ex = getExpertises(userId, expertiseId);
                if(ex != null){
                    res.setExpertise(ex.get(0));
                    List<CrmUserExpertiseItem>  items = getExpertisesItem(userId, expertiseId);
                    res.setItems(items);

                    responses.add(res);
                }
            }
        }

        return  responses;
    }

    public List<CrmUserExpertiseItem> getExpertisesItem(int userId, int expertiseId) {
        String _strSql = " select recid,expertiseid,uploadfileid,filename,recstatus,reccreator,createtime,userid " +
                " from crm_user_expertise_file " +
                " where recstatus = 1 and userid = :userid and expertiseid = :expertiseid " +
                " order by createtime asc ";

        Map<String, Object> _params = new HashMap<>();
        _params.put("userid", userId);
        _params.put("expertiseid", expertiseId);
        return getEntitys(_strSql, _params, CrmUserExpertiseItem.class);
    }

    public List<CrmUserExpertise> getExpertises(int userId, int expertiseId) {
        String _strSql = " select ae.recid,  ae.recname as title, " +
                " (select count(1) from crm_user_expertise_file ef where recstatus = 1 and ef.expertiseid = ae.recid and ef.userid = :userid) as calcount " +
                " from crm_user_auth_expertise ae " +
                " where ae.recstatus = 1 and ae.recid = :expertiseid" +
                " order by ae.recorder ";

        Map<String, Object> _params = new HashMap<>();
        _params.put("userid", userId);
        _params.put("expertiseid", expertiseId);
        return getEntitys(_strSql, _params, CrmUserExpertise.class);
    }

    @Transactional
    public int addExpertiseFile(CrmUserExpertiseItemRequest _request, int userId) {
        int _result = 0;

        CrmUserExpertiseItem item = new CrmUserExpertiseItem();
        item.setRecid(UUID.randomUUID().toString());
        item.setExpertiseid(_request.getExpertiseid());
        item.setUploadfileid(_request.getUploadfileid());
        item.setFilename(_request.getFilename());
        item.setRecstatus(1);
        item.setReccreator(userId);
        item.setCreatetime(new Date());
        item.setUserid(userId);

        String _strSql = " insert into crm_user_expertise_file(recid,expertiseid,uploadfileid,filename,recstatus,reccreator,createtime,userid) " +
                "values(:recid,:expertiseid,:uploadfileid,:filename,:recstatus,:reccreator,:createtime,:userid)";

        Map<String, Object> _params = new HashMap<>();
        _params.put("recid", item.getRecid());
        _params.put("expertiseid", item.getExpertiseid());
        _params.put("uploadfileid", item.getUploadfileid());
        _params.put("filename", item.getFilename());
        _params.put("recstatus", item.getRecstatus());
        _params.put("reccreator", item.getReccreator());
        _params.put("createtime", item.getCreatetime());
        _params.put("userid", item.getUserid());
        _result = updateEntity(_strSql, _params);

        return _result;
    }

    @Transactional
    public int deleteExpertiseFile(String recid, int userid) {
        int _result = 0;

        String _strSql = " update crm_user_expertise_file set recstatus=0 where recid=:recid ";
        Map<String, Object> _params = new HashMap<>();
        _params.put("recid", recid);
        _result = updateEntity(_strSql, _params);

        return _result;
    }

    public List<CrmUser> getUserInfoList(List<String> userids) {
        try {
            String _strSql = " select id,username,password,recstatus,realname " +
                    " from crm_user where id in(:id) ";

            Map<String, Object> _params = new HashMap<>();
            _params.put("id", StringUtil.arrayJoinSplit(userids, ","));
            List<CrmUser> _list = getEntitys(_strSql, _params, CrmUser.class);

            return  _list;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
    }


    //update me info
    @Transactional
    public int updateUserMeInfo(FriendMeSaveRequest _request, int userid) throws Exception {
        int _result = 0;
        try {
            String _strSql = " update crm_user " +
                    " set headimage=:headimage, " +
                    "  realname=:realname, " +
                    "  gender=:gender, " +
                    "  title=:title, " +
                    "  company=:company, " +
                    "  address=:address, " +
                    "  signature=:signature, " +

                    "  resume=:resume, " +
                    "  birthdate=:birthdate, " +
                    "  experience=:experience, " +
                    "  education=:education, " +
                    "  socialfun=:socialfun, " +
                    "  reward=:reward, " +
                    "  languageids=:languageids " +

                    " where id=:id";

            Map<String, Object> _params = new HashMap<>();
            _params.put("headimage", _request.getHeadimage());
            _params.put("realname", _request.getRealname());
            _params.put("gender", _request.getGender());
            _params.put("title", _request.getTitle());
            _params.put("company", _request.getCompany());
            _params.put("address", _request.getAddress());
            _params.put("signature", _request.getSignature());

            _params.put("resume", _request.getResume());
            _params.put("birthdate", _request.getBirthdate());
            _params.put("experience", _request.getExperience());
            _params.put("education", _request.getEducation());
            _params.put("socialfun", _request.getSocialfun());
            _params.put("reward", _request.getReward());
            _params.put("languageids", _request.getLanguageids());

            _params.put("id", userid);
            _result = updateEntity(_strSql, _params);

        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
        return _result;
    }

    @Transactional
    public int inertContactApply(FriendContractApplySaveRequest _request, int userid) {
        int _result = 0;
        try {

            String _strSql = " insert into crm_my_contact_apply(recid,fromuserid,touserid,reccreator)" +
                    " values(:recid,:fromuserid,:touserid,:reccreator)   ";

            List<Integer> _ids = _request.getUserids();
            Map<String, Object> _params = new HashMap<>();
            for (Integer _id : _ids) {
                _params.clear();
                String _recid = UUID.randomUUID().toString();
                _params.put("recid", _recid);
                _params.put("fromuserid", userid);
                _params.put("touserid", _id);
                _params.put("reccreator", userid);
                _result = updateEntity(_strSql, _params);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
        return _result;
    }

    //我收到的好友申请
    public List<FriendListResponse> getContactApplyList(int userid) {
        List<FriendListResponse> _friends = new ArrayList<>();
        try {
            String _strSql = " select a.recid," +
                    " u.id,u.username,u.headimage,u.realname,u.gender,u.title,u.company,u.address,u.signature  " +
                    " from crm_my_contact_apply a " +
                    " inner join crm_user u on u.id=a.fromuserid " +
                    " where a.applystatus=0 " +
                    " and  a.recstatus=1" +
                    " and a.touserid=:touserid" +
                    " order by a.createtime desc";

            Map<String, Object> _params = new HashMap<>();
            _params.put("touserid", userid);
            List<CrmFriend> _tmpFriends = getEntitys(_strSql, _params, CrmFriend.class);
            _friends = toFriendListReponseBath(_tmpFriends);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
        return _friends;
    }

    //跟新好友申请的状态
    @Transactional
    public int updateContactApplyStatus(FriendApplyPassRequest request, int applyStatus) {
        int _result = 0;
        List<FriendContactListResponse> _friends = new ArrayList<>();
        try {
            String _recid = request.getRecid();

            List<CrmContractApply> _applys = getContactApply(_recid);
            if (_applys != null && _applys.size() > 0) {
                CrmContractApply _apply = _applys.get(0);
                int _applyStatus = _apply.getApplystatus();
                int fromuserid = _apply.getFromuserid();
                int touserid = _apply.getTouserid();
                if (_applyStatus == 0) {
                    String _strSql = " update crm_my_contact_apply set applystatus=:applystatus" +
                            " where fromuserid=:fromuserid and touserid=:touserid";
                    Map<String, Object> _params = new HashMap<>();
                    _params.put("applystatus", applyStatus);
//                    _params.put("recid", _recid);
                    _params.put("fromuserid", fromuserid);
                    _params.put("touserid", touserid);
                    _result = updateEntity(_strSql, _params);
                    if (_result > 0) {
                        int _fromUserId = 0;
                        int _toUserId = 0;
                        _fromUserId = _apply.getFromuserid();
                        _toUserId = _apply.getTouserid();
                        insertMyContact(_fromUserId, _toUserId);
                        insertMyContact(_toUserId, _fromUserId);
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
        return _result;
    }

    private List<CrmFriendPart> getMyfriends(int userid) {

        String _strSql = " select recid,userid from crm_my_contact " +
                " where recstatus=1 and  myuserid=:myuserid";
        Map<String, Object> _params = new HashMap<>();
        _params.put("myuserid", userid);
        return getEntitys(_strSql, _params, CrmFriendPart.class);
    }

    private FriendContactListResponse toFriendContactListResponse(CrmUserPart friend) {

        FriendContactListResponse _friend = new FriendContactListResponse();
        _friend.setHeadimage(friend.getHeadimage());
        _friend.setPhone(friend.getUsername());
        _friend.setUserid(friend.getId());
        _friend.setRealname(friend.getRealname());

        _friend.setGender(friend.getGender());
        _friend.setTitle(friend.getTitle());
        _friend.setCompany(friend.getCompany());
        _friend.setAddress(friend.getAddress());
        _friend.setSignature(friend.getSignature());
        _friend.setRecid("");

        return _friend;
    }

    private List<FriendContactListResponse> toContactListReponseBath(List<CrmUserPart> friends) {

        List<FriendContactListResponse> _response = new ArrayList<>();
        for (CrmUserPart f : friends) {
            _response.add(toFriendContactListResponse(f));
        }
        return _response;
    }

    private FriendListResponse toFriendListReponse(CrmFriend friend) {
        FriendListResponse _friend = new FriendListResponse();
        _friend.setHeadimage(friend.getHeadimage());
        _friend.setPhone(friend.getPhone());
        _friend.setUserid(friend.getUserid());
        _friend.setRealname(friend.getRealname());
        _friend.setRecid(friend.getRecid());

        _friend.setGender(friend.getGender());
        _friend.setTitle(friend.getTitle());
        _friend.setCompany(friend.getCompany());
        _friend.setAddress(friend.getAddress());
        _friend.setSignature(friend.getSignature());
        return _friend;
    }

    private List<FriendListResponse> toFriendListReponseBath(List<CrmFriend> friends) {

        List<FriendListResponse> _response = new ArrayList<>();
        for (CrmFriend f : friends) {
            _response.add(toFriendListReponse(f));
        }
        return _response;
    }

    private FriendMeResponse toFriendMeResponse(CrmUserPart2 user) {
        FriendMeResponse _response = new FriendMeResponse();
        _response.setUsername(user.getUsername());
        _response.setHeadimage(user.getHeadimage());
        _response.setRealname(user.getRealname());
        _response.setGender(user.getGender());
        _response.setTitle(user.getTitle());
        _response.setCompany(user.getCompany());
        _response.setAddress(user.getAddress());
        _response.setSignature(user.getSignature());

        _response.setBirthdate(user.getBirthdate());
        _response.setResume(user.getResume());
        _response.setExperience(user.getExperience());
        _response.setEducation(user.getEducation());
        _response.setSocialfun(user.getSocialfun());
        _response.setReward(user.getReward());
        _response.setLanguageids(user.getLanguageids());

        return _response;
    }

    private int insertMyContact(int fromUserId, int toUserId) {

        int _result = 0;
        List<CrmFriendPart> _friends = getMyfriends(fromUserId);
        List<CrmFriendPart> _tmp = _friends.stream().filter(x -> x.getUserid() == toUserId).collect(Collectors.toList());
        if (_tmp != null && _tmp.size() > 0) {
            return 1;
        }

        String _strSql = " insert into crm_my_contact (recid,myuserid,userid,reccreator)" +
                " values(:recid,:myuserid,:userid,:reccreator) ";

        String _recid = UUID.randomUUID().toString();
        Map<String, Object> _params = new HashMap<>();
        _params.put("recid", _recid);
        _params.put("myuserid", fromUserId);
        _params.put("userid", toUserId);
        _params.put("reccreator", fromUserId);
        _result = updateEntity(_strSql, _params);
        return _result;
    }

    public List<CrmContractApply> getContactApply(String applyid) {

        String _strSql = " select recid,fromuserid,touserid,applystatus " +
                " from crm_my_contact_apply where recid=:recid ";
        Map<String, Object> _params = new HashMap<>();
        _params.put("recid", applyid);
        List<CrmContractApply> _applys = getEntitys(_strSql, _params, CrmContractApply.class);
        return _applys;

    }

    public int getUnReadFriendApply(int userid) {

        String _strSql = " select count(1) " +
                " from crm_my_contact_apply " +
                " where hasview=0 and applystatus=0 and  touserid=:touserid ";
        Map<String, Object> _params = new HashMap<>();
        _params.put("touserid", userid);
        int unViewCount = getEntityCount(_strSql, _params);
        return unViewCount;

    }

    public void setApplyHasViewed(int userid) {

        String _strSql = " select  recid,fromuserid,touserid,applystatus " +
                "  from crm_my_contact_apply " +
                "  where hasview=0 and  applystatus=0 and  touserid=:touserid ";
        Map<String, Object> _params = new HashMap<>();
        _params.put("touserid", userid);
        List<CrmContractApply> _applys = getEntitys(_strSql, _params, CrmContractApply.class);

        _strSql = " update crm_my_contact_apply set hasview=1 where recid=:recid";
        for (CrmContractApply a : _applys) {

            _params.clear();
            _params.put("recid", a.getRecid());
            updateEntity(_strSql, _params);
        }
    }
}